﻿using System;
using System.Collections.Generic;
using DimensionsHelper.Common.Contracts.Metadata;

namespace DimensionsHelper.Services.Metadata;

public class Context : MetadataNamedObject, IContext
{
    private readonly List<string> _alternatives;

    internal Context(IMetadataDocument document, ObjectType type, string name)
        : base(document, type, name)
    {
        _alternatives = new List<string>();
    }

    public IReadOnlyList<string> Alternatives => _alternatives;

    public bool IsAlternative(string name)
    {
        return _alternatives.Find(e => e.Equals(name, StringComparison.OrdinalIgnoreCase)) != null;
    }


    public bool SetAlternative(string name)
    {
        if (IsAlternative(name))
        {
            return false;
        }

        _alternatives.Add(name);
        return true;
    }

    public T GetEnumType<T>()
    {
        var type = typeof(T);

        if (type.IsEnum)
        {
            return (T)Enum.Parse(type, Name, true);
        }

        throw new Exception($"类型'{type.Name}'不是枚举类型。");
    }
}


public abstract class ContextsBase<T> : MetadataStringKeyCollection<T>, IContextsBase<T> where T : class, IContext
{
    protected ContextsBase(IMetadataDocument document, ObjectType objectType)
    {
        Document = document;
        BaseName = string.Empty;
        ObjectType = objectType;
        Properties = new Properties(document, this);
        Versioned = true;
    }

    public IProperties Properties { get; }

    public string BaseName { get; internal set; }

    public T Base => GetByKey(BaseName);

    public IMetadataDocument Document { get; }

    public ObjectType ObjectType { get; }

    public IMetadataObject? Parent { get; internal set; }

    public IVersionObjectCollection? Versions { get; internal set; }

    public bool Versioned { get; set; }

    public T1? FindParent<T1>() where T1 : IMetadataObject
    {
        return MetadataObject.FindParent<T1>(this);
    }
}


public class Contexts(IMetadataDocument document) : ContextsBase<IContext>(document, ObjectType.Contexts), IContexts
{
    public override IContext CreateObject(string name)
    {
        return new Context(Document, ObjectType.Context, name);
    }
    
    public IContext AddNew(string name)
    {
        if (TryGetByKey(name, out var context))
        {
            return context;
        }

        context = new Context(Document, ObjectType.Context, name);
        Add(context);

        return context;
    }

    protected override string KeySelector(IContext item)
    {
        return item.Name;
    }
}